package com.changgou.seckill.mq;

import com.alibaba.fastjson.JSON;
import com.changgou.seckill.dao.SeckillGoodsMapper;
import com.changgou.seckill.pojo.SeckillGoods;
import com.changgou.seckill.pojo.SeckillOrder;
import com.changgou.seckill.pojo.SeckillStatus;
import com.changgou.util.IdWorker;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

/*****
 * @Author: 黑马训练营
 * @Description: com.changgou.seckill.mq
 ****/
@Component
@RabbitListener(queues = {"seckillOrderQueue"})
public class SeckillOrderConsumer {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private IdWorker idWorker;

    @Autowired
    private SeckillGoodsMapper seckillGoodsMapper;


    /****
     * 下单操作
     */
    @RabbitHandler
    public void readOrderMessage(String message){
        //获取抢单信息   username,id,time
        SeckillStatus seckillStatus = JSON.parseObject(message,SeckillStatus.class);

        //用户抢单的时候已经实现了重复抢单的排除功能
        //有可能存在未支付的订单  key1=SeckillOrder    key2=username
        //Object order = redisTemplate.boundHashOps("SeckillOrder").get(seckillStatus.getUsername());

        //if(order!=null){
            //更新抢单状态
            //System.out.println("-------存在未支付订单，不允许排队抢单----");
            //return;
        //}

        //从队列中获取该商品的队列值，判断是否有库存
        Object goodsId = redisTemplate.boundListOps("SeckillGoodsCountList_" + seckillStatus.getGoodsId()).rightPop();

        //如果此时商品的队列值为null，则表明该商品售罄
        if(goodsId==null){
            //清理用户排队抢单标识
            clearSeckillStatus(seckillStatus);
            return;
        }
        //商品是否有库存(存在缺陷)->是否超卖
        SeckillGoods seckillGoods = (SeckillGoods) redisTemplate.boundHashOps("SeckillGoods_"+seckillStatus.getTime()).get(seckillStatus.getGoodsId());

        if(seckillGoods!=null && seckillGoods.getStockCount()>0){
            //创建订单对象
            SeckillOrder seckillOrder = new SeckillOrder();
            seckillOrder.setId("No"+idWorker.nextId());
            seckillOrder.setSeckillId(seckillStatus.getGoodsId());
            seckillOrder.setMoney(seckillGoods.getCostPrice());
            seckillOrder.setUserId(seckillStatus.getUsername());
            seckillOrder.setCreateTime(seckillStatus.getCreateTime());
            seckillOrder.setStatus("0");    //未支付
            //将数据存入到Redis
            redisTemplate.boundHashOps("SeckillOrder").put(seckillStatus.getUsername(),seckillOrder);

            //库存递减
            //seckillGoods.setStockCount(seckillGoods.getStockCount()-1);
            //计数器递减
            Long size = redisTemplate.boundHashOps("SeckillGoodsCount").increment(seckillStatus.getGoodsId(), -1);
            seckillGoods.setStockCount(size.intValue());

            //如果此时StockCount==0,商品已经卖完，买完了后需要将数据同步到MySQL中
            //if(seckillGoods.getStockCount()==0){
            if(size==0){
                //同步到数据库中
                seckillGoodsMapper.updateByPrimaryKeySelective(seckillGoods);
                //Redis缓存清理掉
                redisTemplate.boundHashOps("SeckillGoods_"+seckillStatus.getTime()).delete(seckillGoods.getId());
            }else{
                //否则直接同步到Redis即可
                redisTemplate.boundHashOps("SeckillGoods_"+seckillStatus.getTime()).put(seckillGoods.getId(),seckillGoods);
            }

            //更新抢单状态
            seckillStatus.setMoney(Float.valueOf(seckillGoods.getCostPrice()));
            seckillStatus.setOrderId(seckillOrder.getId());
            seckillStatus.setStatus(2); //抢单成功， 等待支付
            stringRedisTemplate.boundValueOps("SeckillStatus_"+seckillStatus.getUsername()).set(JSON.toJSONString(seckillStatus));
        }
    }


    /***
     * 清理用户排队标示信息
     */
    public void clearSeckillStatus(SeckillStatus seckillStatus){
        //排队标示清理
        redisTemplate.delete("UserQueueCount_" + seckillStatus.getUsername());
        //状态清理
        stringRedisTemplate.delete("SeckillStatus_"+seckillStatus.getUsername());
    }
}
